'use strict'

/**
 * <--    还原前    -->
A = (B = (C = (D = !E) * F) >= (G = (H = I * (J = $K === L)) - (M *= M)));

 * <--    特点    -->
 * 一步步向下手动解析
A = B;
  //B = (C = (D = !E) * F) >= (G = (H = I * (J = $K === L)) - (M *= M))
  B = C >= G;
    //C = (D = !E) * F
    C = D * F;
      D = !E;
    //G = (H = I * (J = $K === L)) - (M *= M)
    G = H - M;
      //H = I * (J = $K === L)
      H = I * J;
        J = $K === L;
      M *= M;

 * 按优先级来说，应该由里及外进行计算
 * 那么按遍历的栈过程来说，应该是在出栈的时候拾取path进行还原；
 *  
 * <--    解决办法    -->
 * exit，insertBefore
 * 
 * <--    冗余判断    -->
 * 对赋值语句的顶层赋值表达式不还原，也就避免前面生成的单个赋值表达式进入无线循环
 * 
 * <--    还原后    -->
 * 
D = !E;
C = D * F;
J = $K === L;
H = I * J;
M *= M;
G = H - M;
B = C >= G;
A = B;

 **/

const {parse} = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const t = require('@babel/types');
const generator = require('@babel/generator').default;

let xcode = `A = (B = (C = (D = !E) * F) >= (G = (H = I * (J = $K === L)) - (M *= M)));`;

const visitor = {
    AssignmentExpression:{
        exit:function(path){
            let selfStmt = path.findParent(path => t.isExpressionStatement(path));
            if (!selfStmt || path.parentPath.isExpressionStatement()){
                return;
            }
            selfStmt.insertBefore(t.expressionStatement(path.node));
            path.replaceInline(path.get('left').node);
        },
    },
}

let ast = parse(xcode);
traverse(ast, visitor);
let {code} = generator(ast);
console.log(code);
